<template>
  <div v-loading="loading">
    <template v-if="styleType == 's1'">
      <div class="w-full mt-2">
        <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
      </div>
      <el-select v-model="modelValueLabel" :collapse-tags="true" multiple :placeholder="placeholderText" :size="size" @visible-change="selectClose">
        <el-option style="height: auto; padding: 0" :value="modelValue">
          <el-tree
            ref="selectTree"
            :check-strictly="true"
            :current-node-key="currentNodeKey"
            :data="data"
            :default-checked-keys="checkedKeys"
            :default-expand-all="defaultExpandAll"
            :expand-on-click-node="expandOnClickNode"
            :filter-node-method="filterNode"
            :highlight-current="true"
            :node-key="nodeKey"
            :props="defaultProps"
            :show-checkbox="showCheckbox"
            @check="handleCheck"
            @check-change="handleCheckChange"
            @node-click="handleNodeClick"
          />
        </el-option>
      </el-select>
    </template>

    <template v-if="styleType == 's2'">
      <div class="flex">
        <div>
          <div class="w-full mt-2">
            <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
          </div>
          <div class="border border-gray-200 mt-1 rounded-sm">
            <el-scrollbar :height="height - 40 + 'px'">
              <el-tree
                ref="selectTree"
                :check-strictly="true"
                :current-node-key="currentNodeKey"
                :data="data"
                :default-checked-keys="checkedKeys"
                :default-expand-all="defaultExpandAll"
                :expand-on-click-node="expandOnClickNode"
                :filter-node-method="filterNode"
                :highlight-current="true"
                :node-key="nodeKey"
                :props="defaultProps"
                :show-checkbox="showCheckbox"
                @check="handleCheck"
                @check-change="handleCheckChange"
                @node-click="handleNodeClick"
              />
            </el-scrollbar>
          </div>
        </div>
        <div v-if="getSelectedNodeName.length" class="selectedBox">
          <el-tag v-for="tag in getSelectedNodeName" :key="tag.id" class="selectedNodes" closable :title="tag.path" @close="handleTagClose(tag)">
            {{ tag.name }}
          </el-tag>
        </div>
      </div>
    </template>
  </div>
</template>

<script>
  import cloneDeep from 'lodash/cloneDeep'
  import { defineComponent } from 'vue'
  export default defineComponent({
    name: 'VuiTreeSelect',
    props: {
      // 加载中
      loading: {
        type: Boolean,
        default: false,
      },
      // 区分来源
      name: {
        type: String,
        default: '',
      },
      // 是否默认展开所有节点
      defaultExpandAll: {
        type: Boolean,
        default: true,
      },
      //是否多选
      hasCheckbox: {
        type: Boolean,
        default: false,
      },
      //显示多选
      showCheckbox: {
        type: Boolean,
        default: true,
      },
      //是否在点击节点的时候展开或者收缩节点
      expandOnClickNode: {
        type: Boolean,
        default: true,
      },
      // 直接绑定
      // returnData: {
      //   type: Object,
      //   default: function () {
      //     return {}
      //   },
      // },
      // 样式类型
      styleType: {
        type: String,
        default: 's2', //s1默认 s2直接显示tree
      },
      // 尺寸
      height: {
        type: String,
        default: '300',
      },
      // 大小
      size: {
        type: String,
        default: 'mini',
      },
      placeholderText: {
        type: String,
        default: '请选择...',
      },
      // 字段key， 数据中的id
      nodeKey: {
        type: String,
        default: 'id',
      },
      // 数据
      data: {
        type: Array,
        default: function () {
          return []
        },
      },
      // 回填数据
      checkedKeys: {
        type: Array,
        default: function () {
          return []
        },
      },
      // 当前选中的节点
      currentNodeKey: {
        type: String,
        default: function () {
          return ''
        },
      },

      // 遍历时字段格式化
      defaultProps: {
        type: Object,
        default: function () {
          return {
            children: 'children',
            label: 'label',
          }
        },
      },
    },
    emits: ['checkedChange', 'nodeClick', 'update:modelValue'],
    data() {
      return {
        // 实际选中值
        modelValue: [],
        // 下拉框绑定值(选中值名字)
        modelValueLabel: [],

        // multiples: [], // 多选缓存数据
        filterText: '',
      }
    },
    computed: {
      getSelectedNodeName() {
        const nodes = []
        const eachFunc = (nodeItem, paths) => {
          if (this.checkedKeys.indexOf(nodeItem._id) > -1) {
            nodes.push({
              id: nodeItem._id,
              name: nodeItem.name,
              path: paths.join('->') + `->${nodeItem.name}`,
            })
          }
          nodeItem.list &&
            nodeItem.list.forEach((i) => {
              const pathList = cloneDeep(paths)
              pathList.push(nodeItem.name)
              eachFunc(i, pathList)
            })
        }
        this.data.forEach((i) => eachFunc(i, []))
        return nodes
      },
    },
    watch: {
      filterText(val) {
        this.$refs['selectTree'].filter(val)
      },
    },
    mounted() {
      this.$nextTick(() => {
        this.$refs['selectTree'].filter('')
      })
    },

    methods: {
      //多选回填数据
      // loadMultiples() {
      //   if (this.checkedKeys.length && this.data.length) {
      //     const findTreeItem = (list) => {
      //       list.forEach((v) => {
      //         if (this.checkedKeys.includes(v[this.nodeKey])) {
      //           this.multiples.push(v)
      //         }
      //         if (v.children && v.children.length) {
      //           findTreeItem(v.children)
      //         }
      //       })
      //     }
      //     findTreeItem(this.data)
      //   }
      // },
      selectClose(bool) {
        console.log('selectClose', bool)
      },
      handleNodeClick(item) {
        this.$emit('nodeClick', item)
      },
      handleCheckChange(data, checked) {
        //单选处理
        if (checked) {
          if (!this.hasCheckbox) {
            this.$refs.selectTree.setCheckedKeys([data._id])
          }
        }
      },
      handleCheck(nodes, data) {
        // this.multiples = data.checkedNodes
        console.log('data ---------------- ', data)
        let labels = []
        data.checkedNodes.forEach((v) => {
          labels.push(v[this.defaultProps.label])
        })
        this.modelValue = data.checkedKeys
        this.modelValueLabel = labels
        // emit
        this.$emit('checkedChange', {
          multiples: data.checkedNodes,
          keys: data.checkedKeys,
          name: this.name,
        })
        this.$emit('update:modelValue', data.checkedKeys)
      },
      filterNode(value, data) {
        if (data.hidden !== undefined) {
          return data.hidden !== undefined ? data.name.indexOf(value) !== -1 && !data.hidden : data.name.indexOf(value) !== -1
        }
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      handleTagClose(tagItem) {
        const checkedKeys = this.checkedKeys.filter((i) => i !== tagItem.id)
        this.$refs.selectTree.setCheckedKeys(checkedKeys)
        this.$emit('update:modelValue', checkedKeys)
      },
    },
  })
</script>

<style lang="scss" scoped>
  :deep() {
    // .el-tree-node.is-current > .el-tree-node__content {
    //   background: #999;
    // }
    .selectedNodes {
      margin: 0 5px 5px 0 !important;
      cursor: pointer;
      display: block;
      width: fit-content;
    }

    .el-tree {
      padding-right: 5px;
    }
  }
  .selectedBox {
    margin-left: 10px;
    padding-top: 7px;
    max-height: 350px;
    width: 130px;
    overflow: auto;
    flex: none;
  }
</style>
